package cn.chiship.sdk.core.enums;

/**
 * 请求状态描述
 *
 * @author lijian
 */
public enum StatusEnum {

	/**
	 * 继续
	 */
	CONTINUE(100, "继续",
			"客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收，且仍未被拒绝。客户端应当继续发送请求的剩余部分，或者如果请求已经完成，忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。"),

	/**
	 * 交换协议
	 */
	SWITCHING_PROTOCOLS(101, "交换协议",
			"服务器已经理解了客户端的请求，并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后，服务器将会切换到在Upgrade 消息头中定义的那些协议。"),

	/**
	 * 处理
	 */
	PROCESSING(102, "处理", "由WebDAV（RFC 2518）扩展的状态码，代表处理将被继续执行。"),

	/**
	 * 成功
	 */
	OK(200, "成功", "请求已成功，请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。"),

	/**
	 * 创建
	 */
	CREATED(201, "创建", "请求已经被实现，而且有一个新的资源已经依据请求的需要而建立，且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话，应当返回 '202 Accepted'。"),

	/**
	 * 认可
	 */
	ACCEPTED(202, "认可", "服务器已接受请求，但尚未处理。正如它可能被拒绝一样，最终该请求可能会也可能不会被执行。在异步操作的场合下，没有比发送这个状态码更方便的做法了。"),

	/**
	 * 非授权信息
	 */
	NON_AUTHORITATIVE(203, "非授权信息",
			"服务器已成功处理了请求，但返回的实体头部元信息不是在原始服务器上有效的确定集合，而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如，包含资源的元数据可能导致原始服务器知道元信息的超集。使用此状态码不是必须的，而且只有在响应不使用此状态码便会返回200 OK的情况下才是合适的。"),

	/**
	 * 没有内容
	 */
	NO_CONTENT(204, "没有内容",
			"服务器成功处理了请求，但不需要返回任何实体内容，并且希望返回更新了的元信息。响应可能通过实体头部的形式，返回新的或更新后的元信息。如果存在这些头部信息，则应当与所请求的变量相呼应。"),

	/**
	 * 重置内容
	 */
	RESET_CONTENT(205, "重置内容",
			" 服务器成功处理了请求，且没有返回任何内容。但是与204响应不同，返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后，立即重置表单，以便用户能够轻松地开始另一次输入。"),

	/**
	 * 部分内容
	 */
	PARTIAL_CONTENT(206, "部分内容", "表示服务器成功处理了部分请求，返回了部分内容。通常用于断点续传或分段下载。"),

	/**
	 * 多状态
	 */
	MULTI_STATUS(207, "多状态", "表示服务器已经完成部分请求，并返回多个响应。"),

	/**
	 * 多项选择
	 */
	MULTI_CHOICES(300, "多项选择", "表示请求的资源有多个选择，需要用户选择一个进行访问。"),

	/**
	 * 永久移除
	 */
	MOVED_PERMANENTLY(301, "永久移除", "表示请求的资源已经永久移动到新的URL，浏览器应该使用新的URL重新发送请求。"),

	/**
	 * 暂时移动
	 */
	MOVE_TEMPORARILY(302, "暂时移动", "表示请求的资源已经临时移动到新的URL，浏览器应该使用新的URL重新发送请求。"),

	/**
	 * 查看其他
	 */
	SEE_OTHER(303, "查看其他", "表示请求的资源可以在另一个URL下找到，客户端应该使用GET方法重新发送请求。"),

	/**
	 * 未修改
	 */
	NOT_MODIFIED(304, "未修改", "表示客户端发送的请求的资源在服务器上没有修改，可以直接使用客户端缓存的版本。"),

	/**
	 * 使用代理
	 */
	USE_PROXY(305, "使用代理", "表示请求应该通过代理服务器进行访问。"),

	/**
	 * 交换机代理
	 */
	SWITCH_PROXY(306, "交换机代理", ""),

	/**
	 * 临时重定向
	 */
	TEMPORARY_REDIRECT(307, "临时重定向", "表示请求的资源临时移动到新的URL，浏览器应该使用新的URL重新发送请求。"),

	/**
	 * 错误请求
	 */
	BAD_REQUEST(400, "错误请求", "1、语义有误，当前请求无法被服务器理解。除非进行修改，否则客户端不应该重复提交这个请求。2、请求参数有误。"),

	/**
	 * 未经授权
	 */
	UNAUTHORIZED(401, "未经授权",
			"当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书，那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问，且浏览器已经至少尝试了一次验证，那么浏览器应当向用户展示响应中包含的实体信息，因为这个实体信息中可能包含了相关诊断信息。参见RFC 2617。"),

	/**
	 * 要求付款
	 */
	PAYMENT_REQUIRED(402, "要求付款", "该状态码是为了将来可能的需求而预留的"),

	/**
	 * 被禁止
	 */
	FORBIDDEN(403, "被禁止",
			"服务器已经理解请求，但是拒绝执行它。与401响应不同的是，身份验证并不能提供任何帮助，而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求，而且服务器希望能够讲清楚为何请求不能被执行，那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应，假如它不希望让客户端获得任何信息。"),

	/**
	 * 找不到
	 */
	NOT_FOUND(404, "找不到",
			"请求失败，请求所希望得到的资源未被在服务器上发现。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。出现这个错误的最有可能的原因是服务器端没有这个页面。"),

	/**
	 * 不允许的方法
	 */
	METHOD_ALLOWED(405, "不允许的方法", ""),

	/**
	 * 不可接受
	 */
	NOT_ACCEPTABLE(406, "不可接受", "表示服务器无法根据请求的内容特性生成响应。"),

	/**
	 * 需要代理身份验证
	 */
	PROXY_AUTHENTICATION(407, "需要代理身份验证", ""),

	/**
	 * 请求超时
	 */
	REQUEST_TIMEOUT(408, "请求超时", "表示服务器在等待请求的时间内没有收到任何请求。"),

	/**
	 * 冲突
	 */
	CONFLICT(409, "冲突", ""),

	/**
	 * 不存在
	 */
	GONE(410, "不存在", "表示请求的资源已经永久消失，不再可用。"),

	/**
	 * 要求长度
	 */
	LENGTH_REQUIRED(411, "要求长度", ""),

	/**
	 * 先决条件失败
	 */
	PRECONDITION_FAILED(412, "先决条件失败", ""),

	/**
	 * 请求实体太大
	 */
	REQUEST_ENTITY_TOO_LARGE(413, "请求实体太大", "表示请求的实体太大，服务器无法处理。"),

	/**
	 * 请求URI太长
	 */
	REQUEST_URL_TOO_LONG(414, "请求URI太长", ""),

	/**
	 * 不支持的媒体类型
	 */
	UNSUPPORTED_MEDIA_TYPE(415, "不支持的媒体类型", "表示服务器无法处理请求的媒体类型。"),

	/**
	 * 请求范围不满足
	 */
	REQUESTED_RANGE_NOT_STATISFIABLE(416, "请求范围不满足", ""),

	/**
	 * 执行失败
	 */
	EXPECTATION_FAILED(417, "执行失败", ""),

	/**
	 * 错误的请求
	 */
	MISDIRECTED_REQUEST(421, "错误的请求", ""),

	/**
	 * 不可处理
	 */
	UNPROCESSABLE_ENTITY(422, "不可处理", "请求格式正确，但是由于含有语义错误，无法响应。"),

	/**
	 * 锁定
	 */
	LOCKED(423, "锁定", "当前资源被锁定。"), FAILED_DEPENDENCY(424, "失败的相关项", ""),

	/**
	 * 初期
	 */
	TOO_EARLY(425, "初期", ""),

	/**
	 * 需要升级
	 */
	UPGRADE_REQUIRED(426, "需要升级", ""),

	/**
	 * 太多请求
	 */
	TOO_MANY_REQUESTS(429, "太多请求", "表示客户端发送的请求过多，服务器无法处理。"),

	/**
	 * 重试
	 */
	RETRY_WITH(449, "重试", ""),

	/**
	 * 因法律原因无法获得
	 */
	UNAVAILABLE_FOR_LEGAL_REASONS(451, "因法律原因无法获得", "表示请求的资源因法律原因不可用。"),

	/**
	 * 内部服务器错误
	 */
	INTERNAL_SERVER_ERROR(500, "内部服务器错误", "服务器遇到了一个未曾预料的状况，导致了它无法完成对请求的处理。一般来说，这个问题都会在服务器端的源代码出现错误时出现。"),

	/**
	 * 未执行
	 */
	NOT_IMPLEMENTED(501, "未执行", "服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法，并且无法支持其对任何资源的请求。"),

	/**
	 * 错误的网关
	 */
	BAD_GATEWAY(502, "错误的网关", "作为网关或者代理工作的服务器尝试执行请求时，从上游服务器接收到无效的响应。"),

	/**
	 * 服务不可用
	 */
	SERVICE_UNAVAILABLE(503, "服务不可用",
			" 由于临时的服务器维护或者过载，服务器当前无法处理请求。这个状况是临时的，并且将在一段时间以后恢复。如果能够预计延迟时间，那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息，那么客户端应当以处理500响应的方式处理它。"),

	/**
	 * 网关超时
	 */
	GATEWAY_TIMEOUT(504, "网关超时", " 作为网关或者代理工作的服务器尝试执行请求时，未能及时从上游服务器（URI标识出的服务器，例如HTTP、FTP、LDAP）或者辅助服务器（例如DNS）收到响应。"),

	/**
	 * 不支持的HTTP版本
	 */
	HTTP_VERSION_NOT_SUPPORTED(505, "不支持的HTTP版本", ""),

	/**
	 * 变体协商
	 */
	VARIANT_ALSO_NEGOTIATES(506, "变体协商", ""),

	/**
	 * 存储不足
	 */
	INSUFFICIENT_STORAGE(507, "服务器无法存储完成请求所必须的内容。", ""),

	/**
	 * 超出带宽限制
	 */
	BANDWIDTH_LIMIT_EXCEEDED(509, "超出带宽限制", " 服务器达到带宽限制。这不是一个官方的状态码，但是仍被广泛使用。"),

	/**
	 * 未扩展
	 */
	NOT_EXTENDED(510, "错误的请求", "获取资源所需要的策略并没有被满足。"),

	/**
	 * 无法解析的响应标头
	 */
	UN_PARSEABLE_RESPONSE_HEADERS(600, "无法解析的响应标头", "源站没有返回响应头部，只返回实体内容。"),

	;

	/**
	 * 状态码
	 */
	private Integer code;

	/**
	 * 状态信息
	 */
	private String message;

	/**
	 * 状态描述
	 */
	private String desc;

	StatusEnum(int code, String message, String desc) {
		this.code = code;
		this.message = message;
		this.desc = desc;
	}

	/**
	 * 根据状态值获取枚举
	 * @param code 状态值
	 * @return StatusEnum
	 */
	public static StatusEnum getStatusEnum(Integer code) {
		StatusEnum[] statusEnums = values();
		for (StatusEnum statusEnum : statusEnums) {
			if (statusEnum.getCode().equals(code)) {
				return statusEnum;
			}
		}
		return null;
	}

	public Integer getCode() {
		return code;
	}

	public String getMessage() {
		return message;
	}

	public String getDesc() {
		return desc;
	}

}
